#include"shell.h"
void sendM2All(struct user * shared,char * m){
        int i=0;
        for(;i<31;i++){
                if(shared[i].using==1){
                        write(shared[i].socket_fd,m,strlen(m));
                        if(shared[i].toAll==0)
                        	write(shared[i].socket_fd,"% ",2);
                }
        }
}
void who2(int *socket_fd,struct user *shared_stuff){
        int i;
        char buffer[40960]="<ID>\t<nickname>\t<IP/port>\t<indicate me>\n";
        char buffer2[20000];
        for(i=0;i<31;i++){
                if(shared_stuff[i].using==1){
                          sprintf(buffer2,"%d\t%s\tnctu/5566\t",i+1,shared_stuff[i].name);
                                if(*socket_fd==shared_stuff[i].socket_fd)
                                        strcat(buffer2,"<- me");
                                strcat(buffer2,"\n");
                                strcat(buffer,buffer2);
                        }
                        
        }
        write(*socket_fd,buffer,strlen(buffer));
}
void setenv2(struct commandInfo *cmd,int *socket_fd){
        if(cmd->argv3[0]=='\0')return;
        char strsept[]=" \t";
        char *str_ptr=strtok(cmd->argv3,strsept);
        int i=0;        
        char name[2000];
        char value[200];
                strncpy(name,str_ptr,200);
                str_ptr=strtok(NULL,strsept);
                strncpy(value,str_ptr,200);     
                                                
        for(i=0;i<ENVNUM;i++){
                if(!strncmp(name,env[i].name,200)){
                        strncpy(env[i].content,value,200);
                        break;
                }
        }
}
int socket_read_line_alloc(int sock, char* out) {
        int i = 0;
        char ch;
        for ( ; ; ) {
                if (recv(sock, &ch, 1, 0) == -1) {
                        return -1;
                }
                if (ch == '\n') {
                        out[i] = '\0';
                        break;
                } else {
                        if(ch=='\r')
                                continue;
                        out[i] = ch;
                }
                i++;
        }
        return i + 1;
}
void printenv( struct commandInfo *cmd,int *socket_fd){
        int i;
        char buffer[4096];
        if(cmd->argv3!=NULL&&cmd->argv3[0]!='\0'){
                for(i=0;i<32;i++){
                        if(strlen(env[i].name)!=0&&!strcmp(env[i].name,cmd->argv3)){
                        				sprintf(buffer,"%s=%s\n",cmd->argv3,env[i].content);
                             //   strncpy(buffer,cmd->argv3,4095);
                             //   strcat(buffer,"=")/*,4095-strlen(cmd->argv3))*/;
                             //   strcat(buffer,env[i].content)/*,4095-strlen(cmd->argv3)-1)*/;
                             //   strcat(buffer,"\n")/*,4095-strlen(cmd->argv3)-1-strlen(env[i].content))*/;
                                write(*socket_fd,buffer,strlen(buffer));
                                break;
                        }
                }                                       
        }
}
void name(struct commandInfo *cmd,int * socket_fd,struct user *shared_stuff,pid_t ppid){
        int i;
        for(i=0;i<31;i++){
                if(*socket_fd==shared_stuff[i].socket_fd){
                        strcpy(shared_stuff[i].name,cmd->argv3);
                        break;
                }
        }
        char m[1024];   
        sprintf(m,"*** User  from nctu/5566 is named '%s'. ***\n",cmd->argv3);
        strcpy(shared_stuff[i].m,m);
        shared_stuff[i].toAll=32;
        kill(ppid,SIGUSR1);
}
void yell(struct commandInfo *cmd,int * socket_fd,struct user *shared_stuff,pid_t ppid){
        //char m[10000]="*** ";
        int i;
        for(i=0;i<31;i++){
                if(*socket_fd==shared_stuff[i].socket_fd){
                        break;
                }
        }
        //strcat(m,cmd->argv3);
        sprintf(shared_stuff[i].m,"*** %s yelled ***: %s\n",shared_stuff[i].name,cmd->argv3);
       // strcat(m,shared_stuff[i].name);
        //strcat(m," yelled ***: ");
       // strcat(m,cmd->argv3);
       // strcat(m,"\n");
       // strcpy(shared_stuff[i].m,m);
        shared_stuff[i].toAll=32;
        kill(ppid,SIGUSR1);
}
void tell(struct commandInfo *cmd,int * socket_fd,struct user *shared_stuff,pid_t ppid){
        int i;
        for(i=0;i<31;i++){
                if(*socket_fd==shared_stuff[i].socket_fd){
                        break;
                }
        }
       // char *  token=strtok(cmd->argv3," ");
        if(atoi(cmd->value)<32&&shared_stuff[atoi(cmd->value)-1].using==1){
                shared_stuff[i].toAll=atoi(cmd->value);
                       // char buffer[20480]="*** ";
                        sprintf(shared_stuff[i].m,"*** %s told you ***: %s\n",shared_stuff[i].name,cmd->argv3);
                       // strcat(buffer,shared_stuff[i].name);
                      //  strcat(buffer," told you ***: ");
                       // token=strtok(NULL," "); 
                      //  strcat(buffer,cmd->argv3);
                     //   strcat(buffer,"\n");
                     //   strcpy(shared_stuff[i].m,buffer);
                       // write(*socket_fd,"% ",2);
                        kill(ppid,SIGUSR1);
        }else{
        							char buffer[256];
        							sprintf(buffer,"*** Error: user %s does not exist yet. ***\n",cmd->value);  
                 //       strcat(buffer,cmd->value);
                   //     strcat(buffer," does not exist yet. ***\n");
                        write(*socket_fd,buffer,strlen(buffer));
                        
                }

}

void executeBuiltInCommand(struct commandInfo *cmd,int * socket_fd,struct user *shared_stuff,pid_t ppid ){
        if(!strcmp(cmd->commandName,"printenv"))
                printenv(cmd,socket_fd);
        else if(!strcmp(cmd->commandName,"setenv")){
                setenv2(cmd,socket_fd);}
        else if(!strcmp(cmd->commandName,"who")){
                who2(socket_fd,shared_stuff);
                }
        else if(!strcmp(cmd->commandName,"name")){
                name(cmd,socket_fd,shared_stuff,ppid);
                }
        else if(!strcmp(cmd->commandName,"yell")){
                yell(cmd,socket_fd,shared_stuff,ppid);
                }
        else if(!strcmp(cmd->commandName,"tell")){
                tell(cmd,socket_fd,shared_stuff,ppid);
                }
}
int isBuiltInCommand(struct commandInfo * cmd){
        int len=sizeof(builtInCommand)/POINT_SIZE;
        int i;
        for(i=1;i<len;i++)
                if(!strcmp(builtInCommand[i],cmd->commandName))
                        return i;
        return 0;
}

void init_structCommand(){
        int i; 
        for(i=0;i<COMMANDNUM;i++){
                        memset(&commandList[i],0,sizeof(struct commandInfo));
                        memset(&linepipe[i],0,sizeof(struct lineInfo));
        }
}
int comIndex=0;
int first=0;
void parse(char *cmd,int *client_sockfd,struct user *shared_stuff,int id){
        int i=0;
        char *str_ptr;
        char strsept[]=" \t";
        char tmp_cmd[20000];
        strcpy(tmp_cmd,cmd);
        if(strlen(cmd)==0) return;
        str_ptr=strtok(cmd,strsept);
      //  printf("3dddddddddd %s\n",str_ptr);    
        if(!strcmp(str_ptr,"yell")){
        //	printf("1dddddddddd\n");   
        	  strncpy(commandList[comIndex].commandName,str_ptr,200);
             commandList[comIndex++].booluse=1;
              comIndex%=10000;
                              
        			int i;
        			for(i=4;i<strlen(tmp_cmd);i++)
        				if(tmp_cmd[i]!=' ')
        					break;
        	strcpy(commandList[comIndex-1].argv3,&tmp_cmd[i]);
        	 return ;
        }else if(!strcmp(str_ptr,"tell")){
       // 	printf("2dddddddddd\n");   
        	strncpy(commandList[comIndex].commandName,str_ptr,200);
             commandList[comIndex++].booluse=1;
              comIndex%=10000;
               str_ptr=strtok(NULL,strsept);
              strcpy( commandList[comIndex-1].value,str_ptr);
               for(i=4;i<strlen(tmp_cmd);i++)
        				if(tmp_cmd[i]!=' ')
        					break;
        				i+=2;
               for(;i<strlen(tmp_cmd);i++)
        				if(tmp_cmd[i]!=' ')
        					break;
        				strcpy(commandList[comIndex-1].argv3,&tmp_cmd[i]);
        	return ;
        }else if(!strcmp(str_ptr,"name")){
        //	printf("5dddddddddd\n");   
        	  strncpy(commandList[comIndex].commandName,str_ptr,200);
             commandList[comIndex++].booluse=1;
              comIndex%=10000;
        			int i;
        			for(i=4;i<strlen(tmp_cmd);i++)
        				if(tmp_cmd[i]!=' ')
        					break;
        	strcpy(commandList[comIndex-1].argv3,&tmp_cmd[i]);
        	 return ;
        }
       // printf("4dddddddddd\n");    
        while(str_ptr!=NULL){
                if(!strcmp(str_ptr,"exit")){
                        close(*client_sockfd);
                        shared_stuff[id].using=0;
                        exit(0);
                        }
                if(str_ptr[0]=='-'){
                        strncpy(commandList[comIndex-1].argList,str_ptr,200);
                } 
                else if (str_ptr[0]=='<'){
                				if(str_ptr[1]!='\0'){
													commandList[comIndex-1].ipc_in=atoi(&str_ptr[1]);
											}else {
												str_ptr=strtok(NULL,strsept);
												if(str_ptr==NULL)
															break;
												strncpy(commandList[comIndex-1].inFile,str_ptr,80);
												commandList[comIndex-1].boolInFile=1;
		  									}
                }
                else if (str_ptr[0]=='>'){
                	
                				if(str_ptr[1]=='|'){
															commandList[comIndex-1].ipc_pipe=1;
												}else if(str_ptr[1]=='!'){
															commandList[comIndex-1].ipc_pipe=1;
															commandList[comIndex-1].ipc_pipe2=1;
												}else{
															str_ptr=strtok(NULL,strsept);
															if(str_ptr==NULL)
																	break;
															strncpy(commandList[comIndex-1].outFile,str_ptr,80);
															commandList[comIndex-1].boolOutFile=1;
		  									}
                }
                else if (str_ptr[0]=='|'){
                        i=0;
                        commandList[comIndex-1].pipeTo=str_ptr[1]=='\0'?-1:(atoi(&str_ptr[1]));
                }
                else if (str_ptr[0]=='!'){
                        i=0;
                        commandList[comIndex-1].pipe2To=str_ptr[1]=='\0'?-1:(atoi(&str_ptr[1]));
                }               
                else {
                        if(i==0){
                                strncpy(commandList[comIndex].commandName,str_ptr,200);
                                commandList[comIndex++].booluse=1;
                                comIndex%=10000;
                                i=1;
                        }else {
                                if(strlen(commandList[comIndex-1].argv3)!=0){   
                                        strcat(commandList[comIndex-1].argv3," ");
                                        strcat(commandList[comIndex-1].argv3,str_ptr);
                                }
                                else 
                                        strncpy(commandList[comIndex-1].argv3,str_ptr,200);
                        }
                }
                str_ptr=strtok(NULL,strsept);
        }
}
int checkIsExist(struct commandInfo * cmd,char *root){
        char tmp_root[1000];    
        char *  token=strtok(env[0].content,":");
        while(token!=NULL){
                strncpy(tmp_root,root,1000);
                strcat(tmp_root,token);
                strcat(tmp_root,"/");
                strcat(tmp_root,cmd->commandName);
                FILE *fp=fopen(tmp_root,"r");
                if(fp){
                        strncpy(root,tmp_root,200);
                        fclose(fp);
                        return 1;
                }
                token=strtok(NULL,":"); 
        }
        return 0;

}
void *shared_memory = (void *)0;
struct user *shared_stuff;
void handler(int signo) {
  switch (signo) {
    case SIGCHLD: {
                  
                        int pid=wait(NULL);
                        int i;
                        for(i=0;i<31;i++){
                               
                                        if(shared_stuff[i].pid==pid){
                                        close(shared_stuff[i].socket_fd);
                                        break;
                                        }
                        }
                        char m[1024];
                        sprintf(m,"*** User '%s' left. ***\n",shared_stuff[i].name);
												//strcat(m,shared_stuff[i].name);
												//strcat(m,"' left. ***\n");
												memset(shared_stuff[i].name,0,sizeof(shared_stuff[i].name));
												shared_stuff[i].pid=0;
												shared_stuff[i].id=0;
												shared_stuff[i].socket_fd=0;
												memset(shared_stuff[i].ip,0,sizeof(shared_stuff[i].ip));
												shared_stuff[i].port=0;
												shared_stuff[i].toAll=0;
												memset(shared_stuff[i].buffer,0,sizeof(shared_stuff[i].buffer));
											  memset(shared_stuff[i].m,0,sizeof(shared_stuff[i].m));
												shared_stuff[i].havaValue=0;
												shared_stuff[i].using=0;
												sendM2All(shared_stuff,m);
                        break;
                }
   case SIGUSR1:{
        int i;
                                for(i=0;i<31;i++){
                                        if(shared_stuff[i].toAll!=0){
                                                if(shared_stuff[i].toAll==32){
                                                        sendM2All(shared_stuff,shared_stuff[i].m);
                                                        memset(shared_stuff[i].m,0,strlen(shared_stuff[i].m));
                                                      }
                                                else {
                                                        write(shared_stuff[shared_stuff[i].toAll-1].socket_fd,shared_stuff[i].m,strlen(shared_stuff[i].m));
                                                }
                                                shared_stuff[i].toAll=0;
                                        }
                        }
   break;       
  }
    default:
                 //       fprintf(stderr, "Caught unknown signal: %d\n", signo);
                        break;
    }
}

int main(int argc,char **argv){
				signal( 11, handler );
        chdir("/home/wei/ras");
        unsigned int line=0;
        int server_sockfd, client_sockfd;
        int server_len,client_len;
        char s[100];
        //-----------project 2
                pid_t parentid=getpid();
                int shmid;
                shmid = shmget((key_t)KEY, sizeof(struct user)*31, 0666 | IPC_CREAT);
                if (shmid == -1) {
        fprintf(stderr, "shmget failed1\n");
        exit(EXIT_FAILURE);
        }
        shared_memory = shmat(shmid, (void *)0, 0);
        if (shared_memory == (void *)-1) {
        fprintf(stderr, "shmat failed\n");
        exit(EXIT_FAILURE);
    }
    shared_stuff = (struct user *)shared_memory;
    memset(shared_stuff,0,sizeof(struct user)*31);

        struct sockaddr_in server_address;
        struct sockaddr_in client_address;
        server_sockfd=socket(AF_INET,SOCK_STREAM,0);
        server_address.sin_family=AF_INET;
        server_address.sin_addr.s_addr=htonl(INADDR_ANY);
        server_address.sin_port=htons(atoi(argv[1]));
        server_len=sizeof(server_address);
        bind(server_sockfd,(struct sockaddr *)&server_address,server_len);
        listen(server_sockfd,5);
        
        while(1){
                client_len=sizeof(client_address);
                client_sockfd=accept(server_sockfd,(struct sockaddr *)&client_address,&client_len);
                int i;
                memset(env,0,sizeof(struct envVar)*31);
               // for(i=0;i<32;i++){
               //         memset(env[i].name,0,sizeof(env[i].name));
              //          memset(env[i].content,0,sizeof(env[i].content));
               // }
                //project 2------------------------
                for(i=0;i<31;i++){
                        if(shared_stuff[i].using==0){
                                        shared_stuff[i].using=1;
                                        break;
                                }
                }
                strcpy(shared_stuff[i].name,"(no name)");
                strcpy(shared_stuff[i].ip,(char *)inet_ntoa(client_address.sin_addr));
                shared_stuff[i].socket_fd=client_sockfd;
                char sport[256];
                shared_stuff[i].port=client_address.sin_port;
                char welcome[]="***************************************\r\n**Welcome to the information server. **\r\n***************************************\n";
                write(client_sockfd,welcome,strlen(welcome));
                char messages[128];
                sprintf(messages,"*** User '(no name)' entered from nctu/5566\n",inet_ntoa(client_address.sin_addr),client_address.sin_port);
                sendM2All(shared_stuff,messages);
                //--------------------------------
                init_structCommand();   
                strncpy(env[0].name,"PATH",200);
                strncpy(env[0].content,"bin:.",200);
                int pid;
                signal(SIGCHLD, SIG_DFL);
                signal(SIGUSR1, SIG_DFL);
                if((pid=fork())==0){
                        //project 2 ------------------------------
                        int ix;
                        for(ix=0;ix<31;ix++){
                                        if(shared_stuff[ix].pid!=getpid()&&shared_stuff[ix].pid!=0){
                                        close(shared_stuff[ix].socket_fd);
                                        }
                        }
                        struct user *shared_stuff2=NULL;
                        int shmid2;
                        void *shared_memory2=(void *) 0;
      									shmid = shmget((key_t)KEY, sizeof(struct user)*31,0666);
        								if (shmid == -1){
        								fprintf(stderr,"shmget failed\n");
        								exit(EXIT_FAILURE);
       									}
        								shared_memory2 = shmat(shmid,(void *) 0,0);
        								if (shared_memory2 == (void *)-1){
        									fprintf(stderr,"shmat failed\n");
        									exit(EXIT_FAILURE);
        								}
                			shared_stuff2 = (struct user *)shared_memory2;
    //---------------------
                        int id=i;
                        char cmd[20000];
                        char cmd2[20000];
                        int statval;
                        while(1){
                        	 printf("dddddddddd\n");    
                                socket_read_line_alloc(client_sockfd,cmd);
                                
                                strcpy(cmd2,cmd);
                                line++;
                                int first_command=1;
                                 
                                parse(cmd,&client_sockfd,shared_stuff2,id);  
                               printf("dddddddddd\n");    
                        if(strlen(cmd)==0)
                                comIndex++;
                                //fprintf(stderr,"%d=%d\n",first,comIndex);
                                                        for(i=first;i<comIndex;i++)
                                                        {
                                                        fprintf(stderr,"[%d]\n",line);
                                                        fprintf(stderr,"commandList[%d].boolInfile=%d\n",i,commandList[i].boolInFile);
                                                        fprintf(stderr,"commandList[%d].boolOutfile=%d\n",i,commandList[i].boolOutFile);
                                                        //fprintf(stderr,"commandList[%d].boolBackground=%d\n",i,commandList[i].boolBackground);
                                                        fprintf(stderr,"commandList[%d].argList=%s\n",i,commandList[i].argList);
                                                        fprintf(stderr,"commandList[%d].commandName=%s\n",i,commandList[i].commandName);
                                                        fprintf(stderr,"commandList[%d].pipeTo=%d\n",i,commandList[i].pipeTo);
                                                        fprintf(stderr,"commandList[%d].pipeIn=%d\n",i,commandList[i].pipeIn);
                                                        fprintf(stderr,"commandList[%d].pipe2To=%d\n",i,commandList[i].pipe2To);
                                                        fprintf(stderr,"commandList[%d].inFile=%s\n",i,commandList[i].inFile);
                                                        fprintf(stderr,"commandList[%d].outFile=%s\n",i,commandList[i].outFile);
                                                        fprintf(stderr,"commandList[%d].booluse=%d\n",i,commandList[i].booluse);
                                                        fprintf(stderr,"commandList[%d].value=%s\n",i,commandList[i].value);
                                                        fprintf(stderr,"commandList[%d].argv3=%s\n",i,commandList[i].argv3);
                                                        fprintf(stderr,"\n");
                                                        }
                                                        
                                while(first!=comIndex){
                                        if(isBuiltInCommand(&commandList[first])){
                                                executeBuiltInCommand(&commandList[first],&client_sockfd,shared_stuff2,parentid);
                                                usleep(5);
                                                write(client_sockfd,"% ",2);
                                                memset(&commandList[first],0,sizeof(struct commandInfo));
                                        }
                                        else  {
                                                char buffer[4096]={0};
                                                int pfd[2]={0,0};
                                                if(pipe(pfd)<0)return -1;
                                                switch(commandList[first].pipeTo){
                                                        case -1:
                                                                if(commandList[first+1].pipeIn==0){
                                                                        if(pipe(commandList[first+1].file_pipes)<0){
                                                                                return -1;
                                                                        }
                                                                        else
                                                                                commandList[first+1].pipeIn=1;  
                                                                }
                                                        break;
                                                        case 0:
                                                        break;
                                                        default:
                                                           if(linepipe[line+commandList[first].pipeTo].using==0){
                                                                if(pipe(linepipe[line+commandList[first].pipeTo].file_pipes)<0){
                                                                        return -1;
                                                                }
                                                                else
                                                                        linepipe[line+commandList[first].pipeTo].using=1;
                                                                }
        
                                                }       
                                                switch(commandList[first].pipe2To){
                                                        case -1:
                                                                if(commandList[first+1].pipeIn==0){
                                                                        if(pipe(commandList[first+1].file_pipes)<0)
                                                                                return -1;
                                                                        else
                                                                                commandList[first+1].pipeIn=1;  
                                                                }
                                                        break;
                                                        case 0:
                                                        break;
                                                        default:
                                                                if(linepipe[line+commandList[first].pipe2To].using==0){
                                                                        if(pipe(linepipe[line+commandList[first].pipe2To].file_pipes)<0)
                                                                                return -1;
                                                                        else
                                                                                linepipe[line+commandList[first].pipe2To].using=1;
                                                                }
        
                                                }
                                                
                                                int stderrOutPut=0;
                                                ///------------------------------------------
                                                if(commandList[first].ipc_pipe!=0){
                                                        		if(pipe(shared_stuff2[id].user_pipes)<0)return -1;
																								}
																								int tmp_pipes[2]={0,0};   
																								if(pipe(tmp_pipes)<0)return -1;
																									int f=0;
																									
                                                if(fork()==0){  
                                                 				char root[200]="/home/wei/ras/";       
                                                        if(first_command){
                                                                if(linepipe[line].using==1){
                                                                        dup2(linepipe[line].file_pipes[0],STDIN_FILENO);
                                                                        close(linepipe[line].file_pipes[0]);
                                                                }
                                                        }
                                                        if (commandList[first].pipeIn==1){
                                                                dup2(commandList[first].file_pipes[0],STDIN_FILENO);
                                                                close(commandList[first].file_pipes[0]);
                                                        }else if(commandList[first].ipc_in!=0){
                                                        			if(shared_stuff2[commandList[first].ipc_in-1].havaValue!=0){
                                                        							sprintf(shared_stuff2[id].m,"*** %s (#%d) just received the pipe from %s (#%d) by '%s' ***\n",shared_stuff2[id].name,id+1,shared_stuff2[commandList[first].ipc_in-1].name,commandList[first].ipc_in,cmd2);
                                                        							shared_stuff2[id].toAll=32;
                                                        					shared_stuff2[commandList[first].ipc_in-1].havaValue=0;
                                                        	       write(tmp_pipes[1],shared_stuff2[commandList[first].ipc_in-1].buffer,strlen(shared_stuff2[commandList[first].ipc_in-1].buffer));
																																	memset(shared_stuff2[commandList[first].ipc_in-1].buffer,0,strlen(shared_stuff2[commandList[first].ipc_in-1].buffer));
																																	dup2(tmp_pipes[0],STDIN_FILENO);
																																	close(tmp_pipes[0]);
																																	close(tmp_pipes[1]);
																																}else {
																																	char tb[128];
																																	sprintf(tb,"*** Error: the pipe from #%d does not exist yet. ***",commandList[first].ipc_in);
																																	write(pfd[1],tb,strlen(tb));
																																	if(!checkIsExist(&commandList[first],root)){
																																		sprintf(tb,"\nUnknown command: [%s].\r\n",commandList[first].commandName);
                                                                		write(pfd[1],tb,strlen(tb));
                                                       						 }
																																	close(pfd[1]);
																																	exit(0);
																																}
																												}
                                                        if(commandList[first].pipeTo!=0){
                                                                if(commandList[first].pipeTo==-1){
                                                                        dup2(commandList[(first+1)].file_pipes[1],STDOUT_FILENO);
                                                                        close(commandList[(first+1)].file_pipes[1]);
                                                                }else{
                                                                        dup2(linepipe[line+commandList[first].pipeTo].file_pipes[1],STDOUT_FILENO);
                                                                        close(linepipe[line+commandList[first].pipeTo].file_pipes[1]);
                                                                }
                                                        }else if(commandList[first].pipe2To!=0){
                                                                if(commandList[first].pipe2To==-1){
                                                                        dup2(commandList[(first+1)].file_pipes[1],STDERR_FILENO);
                                                                        //------------------project 2
                                                                        dup2(commandList[(first+1)].file_pipes[1],STDOUT_FILENO);
                                                                        //--------------------------
                                                                        close(commandList[first+1].file_pipes[1]);
                                                                }else{
                                                                        dup2(linepipe[(line+commandList[first].pipe2To)].file_pipes[1],STDERR_FILENO);
                                                                        dup2(linepipe[line+commandList[first].pipe2To].file_pipes[1],STDOUT_FILENO);
                                                                        close(linepipe[line+commandList[first].pipe2To].file_pipes[1]);
                                                                }
                                                                stderrOutPut=1;
                                                        }else if(commandList[first].ipc_pipe!=0){
                                                        					if(shared_stuff2[id].havaValue==1){
                                                        							sprintf(shared_stuff2[id].m,"*** Error: your pipe already exists. ***\n");
                                                        							shared_stuff2[id].toAll=id+1;
                                                        							kill(parentid,SIGUSR1);
                                                        							exit(0);
                                                        					}
                                                        				if(shared_stuff2[id].toAll!=32)
                                                        	      sprintf(shared_stuff2[id].m,"*** %s (#%d) just piped '%s' into his/her pipe. ***\n",shared_stuff2[id].name,id+1,cmd2);
                                                        	      else{
                                                        	      	char mp[5000];
                                                        	      	sprintf(mp,"*** %s (#%d) just piped '%s' into his/her pipe. ***\n",shared_stuff2[id].name,id+1,cmd2);
                                                        	      	strcat(shared_stuff2[id].m,mp);
                                                        	      }
                                                        				shared_stuff2[id].toAll=32;
                                                        				kill(parentid,SIGUSR1);
																																dup2(shared_stuff2[id].user_pipes[1],STDOUT_FILENO);
																																close(shared_stuff2[id].user_pipes[1]);
																																close(shared_stuff2[id].user_pipes[0]);
																																shared_stuff2[id].havaValue=1;
																												}else{
                                                                dup2(pfd[1],STDOUT_FILENO);
                                                        }
                                                        
                                                        if(strlen(commandList[first].commandName)==0){
                                                                        printf("% ");
                                                                        return 0;
                                                        }
                                                        
                                                        if(commandList[first].ipc_pipe2!=0){
																																dup2(STDOUT_FILENO,STDERR_FILENO);
																																stderrOutPut=1;
																												}
                                                        
                                                        if(!stderrOutPut){
                                                                dup2(pfd[1],STDERR_FILENO);
                                                        }
                                                        close(pfd[1]);
                                                        if(commandList[first].boolOutFile==1){
                                                                char fileStrTmp[1024]="/home/wei/ras/";
                                                                strcat(fileStrTmp,commandList[first].outFile);
                                                                int oldfd =open(fileStrTmp,(O_RDWR|O_CREAT),0644);
                                                                dup2(oldfd,1);
                                                                close(oldfd);
                                                        }
                                                        char *argv2[200];
                                                        
                                                        if(!checkIsExist(&commandList[first],root)){
                                                                fprintf(stderr,"Unknown command: [%s].\r\n",commandList[first].commandName);
                                                                return -1;
                                                        }
                                                        int tmp=0;
                                                        int tmp_i;
                                                        char argv4[20][200];
                                                        for(tmp_i=0;;tmp_i++){
                                                                if(tmp_i==0){
                                                                        argv2[tmp++]=(char *)&commandList[first].commandName;
                                                                        continue;
                                                                }
                                                                if(tmp_i==1){
                                                                        if(strlen(commandList[first].argList)!=0)
                                                                                argv2[tmp++]=(char *)&commandList[first].argList;
                                                                        continue;
                                                                }
                                                                char strsept[]=" \t";
                                                                char *str_ptr=strtok(commandList[first].argv3,strsept);
                                                                int i=0;        
                                                            while(str_ptr!=NULL){
                                                                strncpy(argv4[i],str_ptr,200);
                                                                argv2[tmp++]=(char *)&argv4[i++];
                                                                str_ptr=strtok(NULL,strsept);
                                                                }
                                                                break;
                                                                
                                                        }
                                                        argv2[tmp]=(char *)0;
                                                        close(pfd[0]);
                                                        execv(root,(char * const*)argv2);
                                                        fprintf(stderr,"%s exe error\r\n",argv2[1]);
                                                        exit(0);
                                                }else {
                                                	
																												close(tmp_pipes[1]);
                                                        wait(&statval);
                                                        
                                                        close(tmp_pipes[0]);
                                                          if(commandList[first].ipc_pipe!=0){  
                                                        	close(shared_stuff2[id].user_pipes[1]);
                                                        	}
                                                        
                                                        if(shared_stuff2[id].havaValue==1){
                                                        	read(shared_stuff2[id].user_pipes[0],shared_stuff2[id].buffer,4095);
                                                        	 close(shared_stuff2[id].user_pipes[0]);
                                                        }
                                                       
                                                        if(first+1==comIndex){
                                                                if(linepipe[line+1].using==1){
                                                                        close(linepipe[line+1].file_pipes[1]);  
                                                                }
                                                                if(linepipe[line].using==1)
                                                                        close(linepipe[line].file_pipes[0]);
                                                        }
                                                        if(commandList[first].pipeTo==-1||commandList[first].pipe2To==-1)
                                                                        close(commandList[first+1].file_pipes[1]);
                                                        close(pfd[1]);          
                                                        first_command=0;

                                                if(commandList[first].pipeIn){
                                                        close(commandList[(first)].file_pipes[0]);
                                                }

                                                                int len=read(pfd[0],buffer,4095);
                                                                if(strlen(buffer)!=0){
                                                                        if(buffer[len-1]!='\n')
                                                                                strcat(buffer,"\r\n");
                                                                        buffer[len+4]='\0';
                                                                }

                                                                write(client_sockfd,buffer,strlen(buffer));
                                                                kill(parentid,SIGUSR1);
                                                                usleep(500);
                                                /*      }else*/ if((first+1)==comIndex){
                                                                write(client_sockfd,"% ",2);
                                                        }
                                                                close(pfd[0]);
                                                        memset(&commandList[first],0,sizeof(struct commandInfo));
                                                }
                                        }
                                        first++;
                                        first%=10000;
                                }
                        }
                }//if(fork)
                else{
                        signal(SIGCHLD, handler);
                        signal(SIGUSR1, handler);
                        shared_stuff[i].pid=pid;

                }
        }//while(1)
        close(client_sockfd);
}

